Network Objects
What is a network object
Their particularity is that they are bound with a reference.
This concept is really
Regular, Static and Dynamic Network Objects
The concept of Static, Dynamic, and Regular Network Objects only differs by their presence handling over the network.
Here is how you can retrieve the presence for each kind of network objects.
Regular Network Objects
The NetworkObject
trait is the base class for declaring a network object.
The only thing exposed in this class is the reference of the object.
To retrieve the presence of a regular network object reference, you can use its linker, or a parent of the targeted linker (such as the GNOL).
val linker: NetworkObjectLinker[R] = network.gnol
val no: NetworkObject = ???
val presence: Option[NetworkObjectPresence] = linker.findPresence(no.reference)
If the network object is registered in the GNOL tree, linker.findPresence
will return Some(NetworkObjectPresence)
But if the network object isn't registered, or if you try to find the presence of a reference that isn't bound to any network object,
the return value isn't likely to return None
, it could return Some(NetworkObjectPresence)
with the presence state for current engine set to NOT_PRESENT
Dynamic Network Objects
A Dynamic Network Object presence is handled like a regular Network Object,
the only thing is that their presence is exposed in the DynamicNetworkObject
trait.
val dno: DynamicNetworkObject = ???
val presence: NetworkObjectPresence = dno.presence
Static Network Objects
Static Network Objects are specifically handled by the persistence system.
When the serialization process meets a StaticNetworkObject
, it'll suppose that the object is present on any engine, as
it is statically present on the network.
Thus, retrieving a
How to create a Network Object
To create a Network Object, you'll need 3 things:
- Define (or use) a
NetworkObjectReference
. Take a look at the Network Object Reference page to learn more. we'll useMyNetworkObjectReference
as an example. - Define your network object class by extending the NetworkObject interface.
class MyNetworkObject(override val reference: MyNetworkObjectReference) extends NetworkObject[MyNetworkObjectReference]
- Put the instances of this class in a Network Object Linker . You can define your own Network Object Linker, or use the DefaultNetworkObjectLinker as a linker for your objects. You can also prefer the ContextObjectLinker of your PacketChannel.
val ref = MyNetworkReference("tommy")
val myNetworkObject = new MyNetworkObject(ref)
val defaultLinker = network.gnol.defaultNOL
defaultLinker.save(myNetworkObject)
Did not understand a thing of the last sentence ? take a look at Network Object Linker page to understand what is a network object linker, and know what linker you should use depending on the context and your needs.
That's it. Now the framework knows your object,
and if another engine also have an object referenced at MyNetworkReference("tommy")
,
no matters the used linker, the referencing will work.
So what happens if an engine sends a network object that is not referenced on the targeted engine ?
The handling of a network object whose reference is not registered on targeted engine is different depending on the type of Network Object involved:
- Regular / Dynamic Network Objects The object is sent on the distant engine, then the distant engine will register the object's reference.
- Static Network Objects Because they are intended to be static over the network, if an engine receives an unregistered static object reference, it'll throw an exception.
Use cases
Serialize non-serializable objects
The
however, there is still enough reason why serialization/deserialization of an object can be undesirable:
For example, the trait ApplicationContext's implementations objects are just
Relative Objects
Well, as
For this game, we define a trait Player extends NetworkObject[PlayerReference]
and two implementations of Player:
ControlledPlayer
, relative to each connectedengine , which is the player object of thehuman behind the screen that can actually control the playerRemotePlayer
, for remote players that are connected to our session.
We can define a @session/players/controller
) that all ControlledPlayer
objects of the ControlledPlayer#reference
will return the reference @session/players/controller
). using this trick,
once the ControlledPlayer
object is sent to an engine, as Network Object are replaced by their reference during the serialization, the
engines that will receive the reference will take the object referenced at @session/players/controller
, which will result
to its own ControlledPlayer
instance.
This way, we can easily create packets that says 'hey, do something with your own controlled player'
Conversely, we could define a
For engine '@session/players/n
, and then,
we bind our ControlledPlayer
object to the network object reference where '
This way, when we receive or send a player object, we are sure that it will be the ControlledPlayer
) will be
Reinjecting same objects references
Note: Do not be confused between Network Object Reference and a normal object reference. Object References, or a 'reference' is simply the normal reference of an object, the usual term to point to an instance (variables, fields etc) Network Object References are, as said multiple times, the reference of an object
Using
Using a
Using PersistenceConfig and ContextObjectLinker]], it is possible to
Binding a regular object to a network reference using ContextObjectLinkers is sufficient for the objects to be handled as a